import React from 'react';
import {
  ScrollView,
  Text,
  View,
  StyleSheet,
  Dimensions,
  Platform,
  Modal,
} from 'react-native';
import ThemeStyles from '../../styles';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import {getRealSize, RequestCameraPermission, Touchable} from '../../utils';
import FAIcon from 'react-native-vector-icons/FontAwesome';
import Button from '../../components/button';
import Toast from '../../components/toast';
import * as RNImagePicker from 'react-native-image-picker';
import * as profileActionCreator from '../../actions/profile-actions';
import FastImage from 'react-native-fast-image';
import _ from 'lodash';
import config from '../../../config.json';
import {UploadState} from '../../components/file-upload';
import RNFS from 'react-native-fs';
import {connectActionSheet} from '@expo/react-native-action-sheet';
import {v4 as uuid} from 'uuid';
import ConfirmDialog, {DialogMode} from '../../components/confirm-dialog';
import {I18n} from '../../reducers/intl';
import Spinner from '../../components/spinner';

class AlbumScreen extends React.PureComponent {
  static navigationOptions = ({navigation}) => ({
    title: I18n.t('page.title.album'),
    headerBackTitleStyle: Platform.OS === 'ios' && {
      height: 0,
      width: 0,
    },
    headerRight: () => (
      <Touchable onPress={navigation.getParam('onDelete')}>
        <View
          style={[ThemeStyles.Layout.base.padding, {height: getRealSize(48)}]}>
          <Text style={[ThemeStyles.Front.base]}>
            {I18n.t('button.delete')}
          </Text>
        </View>
      </Touchable>
    ),
  });

  state = {
    data: {},
    selectedItem: {},
    loading: false,
  };

  componentDidMount() {
    const {navigation, user} = this.props;
    navigation.setParams({onDelete: () => this.onDelete()});
    const data = {};
    _.get(user, 'album', []).forEach(photo => {
      const uid = uuid();
      data[uid] = {...photo, uid};
    });
    this.setState({data});
  }

  onSelectedItem = uid => {
    const item = this.state.data[uid];
    if (this.state.selectedItem[uid]) {
      delete this.state.selectedItem[uid];
      this.setState({selectedItem: {...this.state.selectedItem}});
    } else {
      this.setState({selectedItem: {...this.state.selectedItem, [uid]: item}});
    }
  };

  onDelete = () => {
    if (Object.values(this.state.selectedItem).length) {
      this.setState({
        dialogVisible: true,
      });
    }
  };

  onRemove = () => {
    const {profileActions} = this.props;
    for (const key in this.state.selectedItem) {
      delete this.state.data[key];
    }
    this.setState({selectedItem: {}, data: {...this.state.data}});
    const newState = Object.values(this.state.data);
    profileActions.updateAlbum(newState);
  };

  onAdd = () => {
    this.props.showActionSheetWithOptions(
      {
        options: this.props.imageOptions,
        cancelButtonIndex: 2,
        destructiveButtonIndex: 2,
        textStyle: {flex: 1},
      },
      index => this.onShowPick(index),
    );
  };

  onShowPick = async index => {
    const upload = this.upload;
    if (index === 0) {
      try {
        await RequestCameraPermission();
      } catch (e) {
        return Toast.show(e.message);
      }
      RNImagePicker.launchCamera(
        {
          mediaType: 'photo',
          includeBase64: false,
          maxHeight: Dimensions.get('screen').height,
          maxWidth: Dimensions.get('screen').width,
        },
        upload,
      );
    } else if (index === 1) {
      RNImagePicker.launchImageLibrary(
        {
          mediaType: 'photo',
          includeBase64: false,
          maxHeight: Dimensions.get('screen').height,
          maxWidth: Dimensions.get('screen').width,
        },
        upload,
      );
    }
  };

  upload = response => {
    const {token, profileActions} = this.props;
    const url = `${config.httpClient.host}/web/image/new`;
    if (response.didCancel) {
      return;
    }
    // {
    //   "fileName": "rn_image_picker_lib_temp_d25c7647-f2a5-48a0-9582-8c0690347bc6.jpg",
    //     "fileSize": 93393,
    //     "height": 293,
    //     "type": "image/jpeg",
    //     "uri": "file:///data/user/0/com.molarapp/cache/rn_image_picker_lib_temp_d25c7647-f2a5-48a0-9582-8c0690347bc6.jpg",
    //     "width": 392
    // }
    const uploadFile = {
      state: UploadState.PENDING,
      name: 'file',
      filename: response.name,
      filepath: Platform.select({
        android: response.uri.replace('file://', ''),
        ios: response.uri.replace('file://', ''),
      }),
      filetype: response.type,
    };
    // console.log(url, token.access, uploadFile);
    const uid = uuid();
    uploadFile.uid = uid;
    const {jobId, promise} = RNFS.uploadFiles({
      toUrl: url,
      files: [uploadFile],
      binaryStreamOnly: false,
      method: 'POST',
      headers: {
        Authorization: `Bearer ${token.access}`,
      },
      beginCallback: jobId => {
        this.setState({
          loading: true,
        });
        // this.setState({
        //   data: {
        //     ...this.state.data,
        //     [uid]: {
        //       ...this.state.data[uid],
        //       rate: 0,
        //       jobId,
        //       state: UploadState.UPLOADING,
        //     },
        //   },
        // });
      },
      progressCallback: response => {
        // const percentage = Math.floor(
        //   (response.totalBytesSent / response.totalBytesExpectedToSend) * 100,
        // );
        // if (percentage % 20 === 0) {
        //   this.setState({
        //     data: {
        //       ...this.state.data,
        //       [uid]: {
        //         ...this.state.data[uid],
        //         jobId: response.jobId,
        //         rate: percentage,
        //         state: UploadState.UPLOADING,
        //       },
        //     },
        //   });
        // }
      },
    });

    // this.setState({
    //   data: {
    //     ...this.state.data,
    //     [uid]: {...uploadFile, jobId},
    //   },
    // });
    promise
      .then(response => {
        //HTTP response响应
        if (response.statusCode == 200) {
          console.log('FILES UPLOADED!'); // response.statusCode状态码, response.headers响应header, response.body 响应body
          const payload = JSON.parse(response.body);
          this.setState(
            {
              data: {
                ...this.state.data,
                [uid]: {
                  ...this.state.data[uid],
                  ...payload.data,
                  state: UploadState.DONE,
                },
              },
            },
            () => {
              profileActions.updateAlbum(Object.values(this.state.data));
            },
          );
        } else {
          console.log('SERVER ERROR');
        }
      })
      .catch(err => {
        //HTTP请求异常
        if (err.description === 'cancelled') {
          // cancelled by user
        }
        console.log(err);
      })
      .finally(() => {
        this.setState({loading: false});
      });
  };

  render() {
    return (
      <View style={Styles.container}>
        <ScrollView
          style={Styles.container}
          showsHorizontalScrollIndicator={false}
          showsVerticalScrollIndicator={false}>
          <View style={Styles.content}>
            {Object.values(this.state.data).map((item, index) => (
              <ImageBlock
                key={item.uid}
                {...item}
                selected={this.state.selectedItem[item.uid]}
                onSelected={() => this.onSelectedItem(item.uid)}
              />
            ))}
          </View>
        </ScrollView>
        <Button label={I18n.t('button.add')} onPress={this.onAdd} />
        <ConfirmDialog
          title={I18n.t('dialog.title.delAlbum')}
          content={I18n.t('dialog.content.confirmDelPhotos')}
          visible={this.state.dialogVisible}
          mode={DialogMode.confirm}
          okLabel={I18n.t('button.delete')}
          cancelLabel={I18n.t('button.close')}
          onConfirm={() => this.onRemove()}
          onClose={() => this.setState({dialogVisible: false})}
        />
        <Spinner
          visible={this.state.loading}
          onClose={() => this.setState({loading: false})}
        />
      </View>
    );
  }
}

const ImageBlock = props => {
  return (
    <Touchable onPress={() => props.onSelected()}>
      <View style={Styles.blockBox}>
        <FastImage
          style={Styles.blockImage}
          source={{
            uri: props.url,
            priority: FastImage.priority.normal,
          }}
          resizeMode={FastImage.resizeMode.contain}
        />
        {props.selected && (
          <FAIcon
            style={Styles.icon}
            name="check-circle-o"
            color={ThemeStyles.Color.primary.color}
            size={getRealSize(16)}
          />
        )}
      </View>
    </Touchable>
  );
};
const mapStateToProps = state => ({
  appState: state.appState,
  user: state.user,
  token: state.token,
  imageOptions: [
    I18n.t('options.image.camera'),
    I18n.t('options.image.album'),
    I18n.t('options.image.close'),
  ],
});

const mapDispatchToProps = dispatch => ({
  profileActions: bindActionCreators(profileActionCreator, dispatch),
});

export default connect(
  mapStateToProps,
  mapDispatchToProps,
)(connectActionSheet(AlbumScreen));

const Styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'transparent',
  },
  content: {
    flexWrap: 'wrap',
    flex: 1,
    flexDirection: 'row',
    marginHorizontal: getRealSize(8),
    paddingBottom: getRealSize(15),
  },
  blockBox: {
    backgroundColor: '#878787',
    marginTop: getRealSize(8),
    marginRight: getRealSize(8),
  },
  blockImage: {
    height: getRealSize(80),
    width: getRealSize(80),
  },
  icon: {
    position: 'absolute',
    bottom: getRealSize(8),
    right: getRealSize(10),
  },
});
